package com.sf.marathon.soul.core.base;

import java.util.HashMap;
import java.util.Map;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.sf.marathon.soul.core.util.StringUtils;

/**
 * 查询条件请求封装（包括分页和排序）<br>
 *
 * @author liutao
 *         2017/6/24 18:48
 */
public class SearchRequest extends EntityWrapper implements Searchable {

    private static final long serialVersionUID = 1L;
    private static final String SPLITOR = "_";
    private static final String BLANK = " ";
    /**
     * <p>
     * 通用的查询条件参数，key: 字段名_操作符 value: 添加的字段值；所有的查询条件都将添加至该params中
     * 在mapper.xml中可使用该方式进行解析
     * <if test="ew!=null and ew.params!=null and ew.params.hasPermission=='true'">
     * </p>
     */
    private Map<String, Object> params = new HashMap<>(4);

    @Override
    public SearchRequest addSearchParam(final String key, final Object value) {
        return addSearchParam(key, value, false);
    }

    @Override
    public SearchRequest addSearchParam(final String key, final Object value, boolean isTableField) {
        String newKey = key;
        // 默认的查询条件为custom
        SearchOperator operator = SearchOperator.custom;
        // 所有查询条件中记录的key值，除custom外，其余都需要加操作符
        String paramKey = key;
        if (key.indexOf(SPLITOR) > -1) {
            String[] keyArr = key.split(SPLITOR);
            newKey = keyArr[0];
            operator = SearchOperator.valueOf(keyArr[1]);
            if (operator == SearchOperator.custom) {
                paramKey = newKey;
            }
        }
        // 添加查询条件
        params.put(paramKey, value);
        StringBuilder sqlWhere = new StringBuilder(20);
        // 表字段名【默认将驼峰转为下划线】
        String tableField = isTableField ? newKey : StringUtils.camelToUnderline(newKey);
        sqlWhere.append(tableField).append(BLANK)
                .append(operator.getSymbol()).append(BLANK)
                .append("{0}");
        // 操作符转换处理
        switch (operator) {
            case in:
                in(tableField, (String) value);
                break;
            case like:
                like(tableField, (String) value);
                break;
            case custom:
                break;
            default:
                where(sqlWhere.toString(), value);
        }
        return this;
    }

    @Override
    public Searchable addAscSort(String columns) {
        String newColumns = StringUtils.camelToUnderline(columns);
        this.orderBy(newColumns);
        return this;
    }

    @Override
    public Searchable addDescSort(String columns) {
        String newColumns = StringUtils.camelToUnderline(columns);
        /**
         * 多字段的降序排序，mysql有点不同
         * order by name,code desc = order by name asc,code desc
         * 需使用这种形式才能达到效果 order by name desc,code desc
         */
        String[] columnArr = newColumns.split(",");
        for (String column : columnArr) {
            this.orderBy(column, false);
        }
        return this;
    }

    public Map<String, Object> getParams() {
        return params;
    }

    /**
     * 获取查询条件对应的参数值，key值的形式：字段名_操作符
     *
     * @param key
     * @return
     */
    @Override
    public Object getSearchParam(final String key) {
        return params.get(key);
    }
}
